import RBXScriptConnectionImpl from "../event/RBXScriptConnectionImpl";


const runService = game.GetService('RunService')
export function setFrameOut(callback: () => void, framenow: number) {
    // print(debug.traceback('setFrameOut'))
    const connect = runService.Stepped.Connect((t, s) => {
        // print('setFrameOut', t, s)
        framenow--;
        if (framenow < 0) {
            if (connect) connect.Disconnect();
        } else if (!framenow) {
            callback();
            if (connect) connect.Disconnect();
        } else {
            return
        }
    })
    // throw ('setFrameOut server')
    return connect
}
export function setFrameInterval(callback: (framenow: number, t?: number, s?: number) => void, frameLife: number, lastFrame?: () => void) {
    // print(debug.traceback('setFrameInterval'))
    let framenow = 0
    const connect = runService.Stepped.Connect((t, s) => {
        // print('setFrameInterval', t, s)
        callback(framenow++, t, s);
        if (frameLife < 0) return
        frameLife--;
        if (!frameLife) {
            if (lastFrame) lastFrame()
            if (connect) connect.Disconnect();
        } else {
            return
        }
    })
    return connect
}
export function setRenderStepped(callback: (framenow: number, s: number) => void, frameLife: number, lastFrame?: () => void) {
    // print(debug.traceback('setFrameInterval'))
    let framenow = 0
    const connect = runService.RenderStepped.Connect((s) => {
        // print('setFrameInterval', t, s)
        callback(framenow++, s);
        if (frameLife < 0) return
        frameLife--;
        if (!frameLife) {
            if (lastFrame) lastFrame()
            if (connect) connect.Disconnect();
        } else {
            return
        }
    })
    return connect
}

/**
 * use Task delay
 * @param time 
 * @param callback 如果disconnected 这个方法不会调用
 * @param final 
 * @returns 
 */
export function setTimeOut(time: number, callback: () => void, onDisconnet?: () => void) {
    const rbx = new RBXScriptConnectionImpl()
    let timeover = false
    const t = task.delay(time, () => {
        timeover = true;
        if (!rbx.disconnected) {
            callback();
        }
    })
    rbx.Disconnect = () => {
        if (onDisconnet) onDisconnet()
        rbx.disconnected = true;
        // print('t', t)
        if (!t) return

        // print('status', status)
        if (!timeover)
            task.cancel(t)
    }
    return rbx
}
export function setInterval(time: number, callback: () => void, onDisconnet?: () => void) {
    const rbx = new RBXScriptConnectionImpl()
    task.spawn(() => {
        while (!rbx.disconnected) {
            task.wait(time);
            if (!rbx.disconnected) {
                callback();
            }
        }
    })
    rbx.Disconnect = () => {
        if (onDisconnet) onDisconnet()
        rbx.disconnected = true;
    }
    return rbx
}
export function setTimeOutNotask(time: number, callback: () => void, final?: () => void) {
    const rbx = new RBXScriptConnectionImpl()
    delay(time, () => {
        if (!rbx.disconnected) {
            callback();
        }
    })

    return rbx
}
